﻿using Kaskelot.SP.Core;
using Kaskelot.SP.Services;
using Kaskelot.SP.UI.CONTROLTEMPLATES.Kaskelot.SP.UI.FormControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Stockholm.SOA.Kaskelot.WCF.DataContracts;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

namespace Kaskelot.SP.UI.WebParts.BlankettPostDetails
{
	[ToolboxItemAttribute(false)]
	public partial class BlankettPostDetails : WebPart
	{
		BlankettPost Post { get; set; }

		public BlankettPostDetails() { }

		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);
			InitializeControl();
		}

		protected void Page_Load(object sender, EventArgs e)
		{
            try
            {
                using (BlankettService svc = new BlankettService())
                {
                    string bpid = this.Page.Request.QueryString[Constants.UrlParameters.BlankettPostId];
                    if (bpid.IsGuid())
                    {
                        Post = svc.GetBlankettPost(new Guid(bpid));
                        if (Post == null)
                        {
                            lblError.Text = "Något gick fel när blanketten skulle laddas. Blanketten kanske är borttagen?";
                            lblError.Visible = true;
                            pnBlankettContainer.Visible = false;
                            return;
                        }

                        if (Post.Status == BlankettPostStatus.Godkänd.ToString())
                        {
                            btnApprove.Visible = false;
                            btnBehandla.Visible = false;
                            btnDeny.Visible = false;
                            MotiveringContainer.Visible = false;
                        }
                        else if (Post.Status == BlankettPostStatus.Nekad.ToString())
                        {
                            MotiveringContainer.Visible = true;
                            MotiveringTextbox.Text = Post.Motivering;
                            btnApprove.Visible = false;
                            btnBehandla.Visible = false;
                            btnDeny.Visible = false;
                        }
                        else if (Post.Blankett.Typ == BlankettTyp.Ansökan && Post.Status == BlankettPostStatus.Inkommen.ToString())
                        {
                            btnBehandla.Visible = true;
                            btnApprove.Visible = true;
                            MotiveringContainer.Visible = false;
                        }
                        else
                        {
                            btnBehandla.Visible = false;
                            btnApprove.Visible = true;
                            MotiveringContainer.Visible = false;
                        }
                    }
                    else
                    {
                        string pid = this.Page.Request.QueryString[Constants.UrlParameters.PersonId];
                        if (pid.IsGuid())
                        {
                            // Find blankett for personid (that has status godkänd?)
                            Post = svc.GetBlankettPostByPerson(new Guid(pid));
                            pnActionButtons.Visible = false;
                            if (Post == null)
                            {
                                lblError.Text = "Användaren har ingen ansökan kopplad till sig.";
                                lblError.Visible = true;
                                pnBlankettContainer.Visible = false;
                                return;
                            }
                        }
                    }

                    pnBlankettContainer.Attributes.Add("data-blankettId", Post.Blankett.Id.ToString());
                    litBlankettNamn.Text = Post.Blankett.Namn;

                    IEnumerable<FaltData> distinctData =
                        from fd in Post.FaltData
                        group fd by fd.Falt into g
                        select new FaltData
                        {
                            Falt = g.Key,
                            Data = string.Join("|", g.Select(fd => fd.Data).ToArray())
                        };

                    rpFalt.DataSource = distinctData;
                    rpFalt.DataBind();
                }

				using (PersonService pSvc = new PersonService())
				{
					Person p = ParsePersonFromFields();
					if (p != null)
					{
						Person existerandePerson = pSvc.GetPersonByPersonnummer(p.Personnummer);

						if(existerandePerson != null){
							litPersonPersonnummer.Text = existerandePerson.Personnummer;
							litPersonNamn.Text = existerandePerson.Fornamn + " " + existerandePerson.Efternamn;
							chkPersonExisterar.Checked = true;
						}
					}
            }
			}
            catch (Exception ex)
            {
				Logger.LogError(this, LayerNames.UI, "Page_Load", "BlankettPostDetails.ascx.cs Page_Load misslyckades", ex);
            }
		}

		protected void rpBlankettFalt_ItemDataBound(object sender, RepeaterItemEventArgs e)
		{
			try
			{
				if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
				{
					FaltData falt = (FaltData)e.Item.DataItem;

					string basePath = "/_controltemplates/Kaskelot.SP.UI/FormControls/";
					FormControl ctrl = Page.LoadControl(basePath + UserControlForTyp(falt.Falt.Typ)) as FormControl;
					ctrl.FaltData = falt;

					PlaceHolder phFalt = e.Item.FindControl("phFalt") as PlaceHolder;
					phFalt.Controls.Add(ctrl);
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private static string UserControlForTyp(FaltTyp typ)
		{
			switch (typ)
			{
				case FaltTyp.Flerval:
					return "Flerval.ascx";
				case FaltTyp.Datum:
					return "Datum.ascx";
				case FaltTyp.Enkelval:
					return "Enkelval.ascx";
				case FaltTyp.Textrad:
					return "Textrad.ascx";
				case FaltTyp.Textyta:
					return "Textyta.ascx";
				case FaltTyp.Personnummer:
					return "Personnummer.ascx";
				case FaltTyp.Epostadress:
					return "Mailadress.ascx";
				case FaltTyp.Postnummer:
					return "Postnummer.ascx";
				default:
					return string.Empty;
			}
		}

		private string FindDataForFieldName(string name)
		{
			foreach (FaltData data in Post.FaltData)
				if (data.Falt.Namn.ToLower().Contains(name.ToLower()))
					return data.Data;

			return null;
		}

		private Person ParsePersonFromFields()
		{
			string fnamn = FindDataForFieldName("Förnamn");
			string enamn = FindDataForFieldName("Efternamn");
			string personnummer = FindDataForFieldName("Personnummer");
			string epost = FindDataForFieldName("Epost");
			string gatuadress = FindDataForFieldName("Adress");
			string postnr = FindDataForFieldName("Postnummer");
			string postort = FindDataForFieldName("Postort");
			string telnr = FindDataForFieldName("Telefon");
			string mobtelnr = FindDataForFieldName("Mobil");
			string kommentar = FindDataForFieldName("Kommentar");
			string ovrigt = FindDataForFieldName("Övrigt");

			Person p = new Person()
			{
				Id = Guid.NewGuid(),
				Fornamn = fnamn,
				Efternamn = enamn,
				Personnummer = personnummer,
				Epost = epost,
				SkapadAv = SPContext.Current.Web.CurrentUser.LoginName,
				Skapad = DateTime.Now,
				ValId = ApplicationContext.Current.Val.Id,
				Typer = new PersonTyp[0],
				GatuAdress = gatuadress,
				PostNr = postnr,
				PostOrt = postort,
				TelNr = telnr,
				MobTelNr = mobtelnr,
				Fritext = string.Join(" ", new string[] { kommentar, ovrigt })
			};

			return p;
		}

		private void GoToPersonDetails(string id)
		{
			HttpContext.Current.Response.Redirect(SPContext.Current.Site.Url + "/" + Constants.Person.WebName + "/" + PublishingWeb.GetPublishingWeb(SPContext.Current.Web).PagesListName + "/" + Constants.Person.Pages.DetailsPage + "?" + Constants.UrlParameters.PersonId + "=" + id);
		}

		protected void btnDeny_Click(object sender, EventArgs e)
		{
			try
			{
				if (Post != null)
				{
					Person p = ParsePersonFromFields();

					using (BlankettService blankettSvc = new BlankettService())
					{
						Post.Status = BlankettPostStatus.Nekad.ToString();
						Post.Motivering = tbMotivation.Text;
						blankettSvc.UpdateBlankettPost(Post);
					}

					HttpContext.Current.Response.Redirect("default.aspx#tab-4");
				}
			}
			catch (ArgumentException ex)
			{
				lblError.Text = "Blanketten kunde inte nekas: " + ex.Message;
				lblError.Visible = true;
				return;
			}
			catch (Exception)
			{
				throw;
			}
		}

		protected void btnBehandla_Click(object sender, EventArgs e)
		{
			ChangeStatus(BlankettPostStatus.Behandlas);
			btnApprove.Visible = true;
			btnBehandla.Visible = false;
		}

		protected void btnApprove_Click(object sender, EventArgs e)
		{
			ChangeStatus(BlankettPostStatus.Godkänd);
		}

		private void ChangeStatus(BlankettPostStatus status)
		{
			try
			{
				if (Post != null)
				{
					Person p = ParsePersonFromFields();

					if (string.IsNullOrEmpty(p.Fornamn))
						throw new ArgumentException("Ingen information kunde hittas för fältet: \"" + "Förnamn" + "\"");
					if (string.IsNullOrEmpty(p.Efternamn))
						throw new ArgumentException("Ingen information kunde hittas för fältet: \"" + "Efternamn" + "\"");
					if (string.IsNullOrEmpty(p.Epost))
						throw new ArgumentException("Ingen information kunde hittas för fältet: \"" + "Epost" + "\"");
					if (string.IsNullOrEmpty(p.Personnummer))
						throw new ArgumentException("Ingen information kunde hittas för fältet: \"" + "Personnummer" + "\"");
					if (!p.Epost.IsValidEpost())
						throw new ArgumentException("Ej giltig epostadress.");
					if (!p.Personnummer.IsValidPersNr())
						throw new ArgumentException("Ett giltigt personnummer enligt formatet ÅÅÅÅMMDD-XXXX krävs.");

					string activePersonId = string.Empty;

					using (PersonService personSvc = new PersonService())
					using (BlankettService blankettSvc = new BlankettService())
					{
						Person existingPerson = personSvc.GetPersonByPersonnummer(p.Personnummer);
						if (existingPerson != null)
						{
							if (p.Fornamn.IsNonEmpty()) existingPerson.Fornamn = p.Fornamn;
							if (p.Efternamn.IsNonEmpty()) existingPerson.Efternamn = p.Efternamn;
							if (p.Epost.IsNonEmpty()) existingPerson.Epost = p.Epost;
							if (p.MobTelNr.IsNonEmpty()) existingPerson.MobTelNr = p.MobTelNr;
							if (p.TelNr.IsNonEmpty()) existingPerson.TelNr = p.TelNr;
							if (p.PostNr.IsNonEmpty()) existingPerson.PostNr = p.PostNr;
							if (p.PostOrt.IsNonEmpty()) existingPerson.PostOrt = p.PostOrt;
							if (p.GatuAdress.IsNonEmpty()) existingPerson.GatuAdress = p.GatuAdress;
						}

						switch (Post.Blankett.Typ)
						{
							case BlankettTyp.Ansökan:
								{
									// Ansökan godkänd och person uppdaterad
									if (existingPerson != null)
									{
										if (status == BlankettPostStatus.Godkänd)
										{
											existingPerson.AnsokanGodkand = true;
											personSvc.UpdatePerson(existingPerson);

											if (existingPerson.Typer.Where(x => x.Id == PersonTyp.RostmottagareFTTypId).Count() == 0)
												personSvc.CreatePersonPersonTyp(existingPerson.Id, PersonTyp.RostmottagareFTTypId);

											Post.PersonId = existingPerson.Id;
										}
									}
									else // Ansökan godkänd och person skapad
									{
										if (status == BlankettPostStatus.Godkänd)
										{
											p.AnsokanGodkand = true;
											personSvc.CreatePerson(p);
											personSvc.CreatePersonPersonTyp(p.Id, PersonTyp.RostmottagareFTTypId);
											
											Post.PersonId = p.Id;
										}
									}

									// Uppdatera status på ansökan
									Post.Status = status.ToString();
									blankettSvc.UpdateBlankettPost(Post);

									activePersonId = Post.PersonId.ToString();

									if (status == BlankettPostStatus.Godkänd)
										HttpContext.Current.Response.Redirect("../../Person/Sidor/details.aspx?PersonId=" + activePersonId);
									else if (status == BlankettPostStatus.Behandlas)
										HttpContext.Current.Response.Redirect("default.aspx#tab-4");

									break;
								}
							case BlankettTyp.Intresseanmälan:
								{
									// Anmälan godkänd och person uppdaterad
									if (existingPerson != null)
									{
										existingPerson.AnmalanGodkand = true;
										personSvc.UpdatePerson(existingPerson);

										if (existingPerson.Typer.Where(x => x.Id == PersonTyp.RostmottagareTypId).Count() == 0)
											personSvc.CreatePersonPersonTyp(existingPerson.Id, PersonTyp.RostmottagareTypId);

										activePersonId = existingPerson.Id.ToString();
									}
									else // Anmälan godkänd och person skapad
									{
										p.AnmalanGodkand = true;
										personSvc.CreatePerson(p);
										personSvc.CreatePersonPersonTyp(p.Id, PersonTyp.RostmottagareTypId);
										activePersonId = p.Id.ToString();
									}

									// Ta bort anmälan
									blankettSvc.DeleteBlankettPost(Post.Id);

									HttpContext.Current.Response.Redirect("../../Person/Sidor/details.aspx?PersonId=" + activePersonId);

									break;
								}
							default: return;
						}
					}
				}
			}
			catch (ArgumentException ex)
			{
				lblError.Text = "Blanketten kunde inte godkännas: " + ex.Message;
				lblError.Visible = true;
				return;
			}
			catch (Exception)
			{
				throw;
			}
		}
	}
}
